package com.zzuli.yxy.task;

import com.zzuli.yxy.entity.Album;
import com.zzuli.yxy.entity.Singer;
import com.zzuli.yxy.entity.Song;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zzuli.yxy.service.SongService;
import com.zzuli.yxy.task.springDataPipeline.SingerNamePipeline;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;
import us.codecraft.webmagic.scheduler.QueueScheduler;
import us.codecraft.webmagic.selector.Selectable;

import java.util.LinkedList;
import java.util.List;

/**
 * 目标地址：https://music.163.com/song?id=2026224214
 * 解析歌曲图片、歌曲歌手、歌曲歌手id，歌曲所属专辑
 * @auther pony
 * @create 2023-04-04 17:20
 */
@Component
public class SingerNameTask implements PageProcessor {

    private String basicUrl = "https://music.163.com/song?id=";
    @Autowired
    private SongService songService;

    //一首歌的歌手可能不止一个，这里我们把歌手信息放到 list 集合里
    private List<Singer> singerList = new LinkedList<>();

    @Override
    public void process(Page page) {
        Song song = new Song(); // 封装 id 和 歌曲图片
        Album album = new Album(); //封装 id 和 专辑名字
        //1、 根据路径，获取歌曲id
        String url = page.getUrl().toString();
        System.out.println("url:"+url);
        // 截取获得 songId
        String songId = url.substring(url.lastIndexOf("=") + 1);
        System.out.println("songId:"+songId);
        //2、 获取图片地址
        //转 string <img src="http://p2.music.126.net/cGTKkFl5qcXIDYPo7PrmDA==/109951168431655039.jpg?param=130y130" class="j-img" data-src="http://p2.music.126.net/cGTKkFl5qcXIDYPo7PrmDA==/109951168431655039.jpg">
        String img = page.getHtml().css("div.u-cover img.j-img").toString();

        // 字符串截取 http://p2.music.126.net/cGTKkFl5qcXIDYPo7PrmDA==/109951168431655039.jpg?param=130y130
        String imgUrl = img.substring(img.indexOf("src=\"") + 5, img.indexOf("class")-2);
        System.out.println("links" + imgUrl);

        //3、封装 song 数据
        song.setSongId(Integer.valueOf(songId));
        song.setSongImg(imgUrl);

        page.putField("song", song);

        //4、 获取 歌手 id 和 歌手名
//        List<String> singerUrlList = page.getHtml().css("div.cnt p.des span a").links().all();
        List<String> singerAList = page.getHtml().css("div.cnt p.des span a").all();
        System.out.println("selectable:"+singerAList);
        for (String singerA : singerAList) {
            Singer singer = new Singer(); // 封装 id 和 歌手名
            // 截取获得 singerId
            // <a class="s-fc7" href="/artist?id=12193174">Capper</a>
            System.out.println("singerA:" + singerA );
            String singerId = singerA.substring(singerA.lastIndexOf("id=") + 3, singerA.lastIndexOf("\""));
            // 12193174
            System.out.println("singerId:"+singerId);

            // 截取获得 singerName
            String singerName = singerA.substring(singerA.lastIndexOf("\">") + 2, singerA.lastIndexOf("</a>"));
            System.out.println("singerName:"+singerName);

            // 封装数据
            singer.setSingerId(Integer.valueOf(singerId));
            singer.setSingerName(singerName);

            singerList.add(singer);
        }
        page.putField("singerList", singerList);

        // 获取专辑 id 和 名字
        String albumUrl = page.getHtml().xpath("//div[@class=cnt]/p/a").links().toString();
        System.out.println("albumUrl:"+albumUrl);
        String albumId = albumUrl.substring(albumUrl.lastIndexOf("id=") + 3);
        System.out.println("albumId:"+albumId);
        Selectable selectable = page.getHtml().xpath("//div[@class=cnt]/p/a");
        String albumName = selectable.css("a", "text").toString();
        System.out.println("albumName:" + albumName);
        // 封装数据
        album.setAlbumId(Integer.valueOf(albumId));
        album.setAlbumName(albumName);

        page.putField("album", album);
    }

    private Site site = Site.me();
    @Override
    public Site getSite(){
        return site;
    }

    @Autowired
    private SingerNamePipeline singerNamePipeline;
//    @Scheduled(initialDelay = 1 * 1000, fixedRate=1000*60*60*24*7)
    public void process(){
        //1、查询数据库，获取所有歌曲
        List<Song> songlist = songService.list();
        //2、遍历 songList，得到每首歌的 id
        for (Song song : songlist) {
            // 3、通过id，拼接要爬虫地址
            Integer songId = song.getSongId();
            String url = basicUrl + songId;
            // 4、配置请求信息
            Request request = new Request(url);
            // 请求方法
            request.setMethod("GET");
            // 浏览器基本信息，用于反爬
            request.addHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36");

            Spider.create(new SingerNameTask())
                    .addRequest(request)
                    // 使用布隆过滤器进行去重， 10000 大概要放的数据，数据越大越慢
                    // 使用前先引一个新版本的依赖
                    .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000)))
                    .thread(10)
                    .addPipeline(this.singerNamePipeline)
                    .run();
        }
    }
}
